<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>五子棋 - 经典游戏</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#8B5A2B',      // 主色调：棕色
                        secondary: '#D2B48C',    // 辅助色：棕褐色
                        accent: '#4A2510',       // 强调色：深棕色
                        board: '#E6C196',        // 棋盘色：木色
                        blackStone: '#000000',   // 黑棋
                        whiteStone: '#FFFFFF',   // 白棋
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .board-grid {
                background-image: linear-gradient(#000 1px, transparent 1px),
                linear-gradient(90deg, #000 1px, transparent 1px);
            }
            .stone-shadow {
                box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
            }
            .win-line {
                animation: pulse 1.5s infinite;
            }
            @keyframes pulse {
                0%, 100% { opacity: 1; }
                50% { opacity: 0.6; }
            }
        }
    </style>
</head>
<body class="bg-gradient-to-br from-amber-50 to-amber-100 min-h-screen flex flex-col items-center justify-center p-4">
<div class="max-w-4xl w-full mx-auto bg-white rounded-2xl shadow-xl overflow-hidden">
    <!-- 游戏标题区域 -->
    <header class="bg-primary text-white p-6 text-center">
        <h1 class="text-[clamp(1.8rem,5vw,2.5rem)] font-bold tracking-tight">五子棋</h1>
        <p class="text-amber-100 mt-2">落子连五获胜的经典策略游戏</p>
    </header>

    <!-- 游戏主体区域 -->
    <main class="flex flex-col md:flex-row">
        <!-- 游戏信息面板 -->
        <div class="w-full md:w-1/4 p-6 bg-amber-50 border-b md:border-b-0 md:border-r border-amber-200">
            <div class="mb-6">
                <h2 class="text-lg font-semibold text-primary mb-3 flex items-center">
                    <i class="fa fa-info-circle mr-2"></i>游戏状态
                </h2>
                <div class="flex items-center justify-between bg-white p-4 rounded-lg shadow-sm">
                    <div class="flex items-center">
                        <div id="current-player-icon" class="w-8 h-8 rounded-full bg-blackStone stone-shadow"></div>
                        <span id="current-player-text" class="ml-3 font-medium">黑方回合</span>
                    </div>
                    <div id="game-status" class="text-sm px-3 py-1 rounded-full bg-green-100 text-green-800">
                        游戏进行中
                    </div>
                </div>
            </div>

            <div class="mb-6">
                <h2 class="text-lg font-semibold text-primary mb-3 flex items-center">
                    <i class="fa fa-trophy mr-2"></i>游戏记录
                </h2>
                <div class="bg-white rounded-lg shadow-sm p-4 max-h-48 overflow-y-auto">
                    <ul id="game-history" class="space-y-2 text-sm">
                        <li class="text-gray-500 italic">游戏开始</li>
                    </ul>
                </div>
            </div>

            <div class="space-y-3">
                <button id="restart-btn" class="w-full bg-primary hover:bg-accent text-white py-3 px-4 rounded-lg transition-all duration-300 flex items-center justify-center">
                    <i class="fa fa-refresh mr-2"></i>重新开始
                </button>
                <button id="undo-btn" class="w-full bg-amber-600 hover:bg-amber-700 text-white py-3 px-4 rounded-lg transition-all duration-300 flex items-center justify-center">
                    <i class="fa fa-undo mr-2"></i>悔棋
                </button>
                <button id="hint-btn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-3 px-4 rounded-lg transition-all duration-300 flex items-center justify-center">
                    <i class="fa fa-lightbulb-o mr-2"></i>提示
                </button>
            </div>
        </div>

        <!-- 棋盘区域 -->
        <div class="w-full md:w-3/4 p-4 md:p-8 flex items-center justify-center relative bg-gradient-to-br from-amber-50 to-amber-100">
            <div class="relative">
                <!-- 棋盘容器 -->
                <div id="board-container" class="relative bg-board rounded-lg shadow-lg overflow-hidden">
                    <canvas id="board" class="cursor-pointer"></canvas>
                    <!-- 胜利提示会覆盖在棋盘上 -->
                    <div id="win-message" class="hidden absolute inset-0 bg-black/50 flex items-center justify-center">
                        <div class="bg-white p-8 rounded-xl shadow-2xl text-center transform transition-all">
                            <h3 class="text-2xl font-bold text-primary mb-4">游戏结束</h3>
                            <p id="winner-text" class="text-xl mb-6">黑方获胜！</p>
                            <button id="new-game-btn" class="bg-primary hover:bg-accent text-white py-2 px-6 rounded-lg transition-all">
                                开始新游戏
                            </button>
                        </div>
                    </div>
                </div>

                <!-- 游戏控制提示 -->
                <div class="mt-4 text-center text-sm text-gray-600">
                    <p>在棋盘上点击落子，连成五子即可获胜</p>
                </div>
            </div>
        </div>
    </main>

    <!-- 页脚 -->
    <footer class="bg-primary text-white text-center py-4 text-sm">
        <p>© 2025 五子棋游戏 | 一个精美的Web实现</p>
    </footer>
</div>

<script>
    document.addEventListener('DOMContentLoaded', () => {
        // 游戏常量
        const BOARD_SIZE = 15;  // 15x15的棋盘
        const CELL_SIZE = 30;   // 每个格子的大小(像素)
        const BOARD_PADDING = 40; // 棋盘边缘的内边距
        const STONE_SIZE = CELL_SIZE * 0.45; // 棋子大小

        // 游戏状态
        let gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(0));
        let currentPlayer = 1; // 1: 黑方, 2: 白方
        let gameOver = false;
        let moveHistory = []; // 记录每一步棋
        let hintPosition = null; // 提示位置

        // 获取DOM元素
        const canvas = document.getElementById('board');
        const ctx = canvas.getContext('2d');
        const boardContainer = document.getElementById('board-container');
        const currentPlayerIcon = document.getElementById('current-player-icon');
        const currentPlayerText = document.getElementById('current-player-text');
        const gameStatus = document.getElementById('game-status');
        const gameHistory = document.getElementById('game-history');
        const restartBtn = document.getElementById('restart-btn');
        const undoBtn = document.getElementById('undo-btn');
        const hintBtn = document.getElementById('hint-btn');
        const winMessage = document.getElementById('win-message');
        const winnerText = document.getElementById('winner-text');
        const newGameBtn = document.getElementById('new-game-btn');

        // 设置画布尺寸
        function setupCanvas() {
            const size = CELL_SIZE * (BOARD_SIZE - 1) + BOARD_PADDING * 2;
            canvas.width = size;
            canvas.height = size;
            boardContainer.style.width = `${size}px`;
            boardContainer.style.height = `${size}px`;
        }

        // 绘制棋盘
        function drawBoard() {
            const boardSize = CELL_SIZE * (BOARD_SIZE - 1);
            const totalSize = canvas.width;

            // 绘制棋盘背景
            ctx.fillStyle = '#E6C196'; // 木色
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // 绘制网格线
            ctx.strokeStyle = '#000';
            ctx.lineWidth = 1;

            // 绘制横线和竖线
            for (let i = 0; i < BOARD_SIZE; i++) {
                // 横线
                const y = BOARD_PADDING + i * CELL_SIZE;
                ctx.beginPath();
                ctx.moveTo(BOARD_PADDING, y);
                ctx.lineTo(BOARD_PADDING + boardSize, y);
                ctx.stroke();

                // 竖线
                const x = BOARD_PADDING + i * CELL_SIZE;
                ctx.beginPath();
                ctx.moveTo(x, BOARD_PADDING);
                ctx.lineTo(x, BOARD_PADDING + boardSize);
                ctx.stroke();
            }

            // 绘制5个天元点
            const dots = [
                {x: 3, y: 3}, {x: 11, y: 3},
                {x: 7, y: 7},
                {x: 3, y: 11}, {x: 11, y: 11}
            ];

            dots.forEach(dot => {
                const x = BOARD_PADDING + dot.x * CELL_SIZE;
                const y = BOARD_PADDING + dot.y * CELL_SIZE;

                ctx.beginPath();
                ctx.arc(x, y, 3, 0, Math.PI * 2);
                ctx.fillStyle = '#000';
                ctx.fill();
            });

            // 绘制棋子
            for (let i = 0; i < BOARD_SIZE; i++) {
                for (let j = 0; j < BOARD_SIZE; j++) {
                    if (gameBoard[i][j] !== 0) {
                        const x = BOARD_PADDING + j * CELL_SIZE;
                        const y = BOARD_PADDING + i * CELL_SIZE;
                        drawStone(x, y, gameBoard[i][j]);
                    }
                }
            }

            // 绘制提示标记
            if (hintPosition && !gameOver) {
                const {x, y} = hintPosition;
                const boardX = BOARD_PADDING + y * CELL_SIZE;
                const boardY = BOARD_PADDING + x * CELL_SIZE;

                ctx.beginPath();
                ctx.arc(boardX, boardY, STONE_SIZE * 0.8, 0, Math.PI * 2);
                ctx.strokeStyle = '#FF0000';
                ctx.lineWidth = 2;
                ctx.setLineDash([5, 3]); // 虚线效果
                ctx.stroke();
                ctx.setLineDash([]); // 重置虚线
            }
        }

        // 绘制棋子
        function drawStone(x, y, player) {
            ctx.beginPath();
            ctx.arc(x, y, STONE_SIZE, 0, Math.PI * 2);

            // 渐变效果
            const gradient = ctx.createRadialGradient(
                x - STONE_SIZE * 0.3, y - STONE_SIZE * 0.3, STONE_SIZE * 0.1,
                x, y, STONE_SIZE
            );

            if (player === 1) {
                // 黑棋渐变
                gradient.addColorStop(0, '#555');
                gradient.addColorStop(1, '#000');
            } else {
                // 白棋渐变
                gradient.addColorStop(0, '#fff');
                gradient.addColorStop(1, '#ddd');
            }

            ctx.fillStyle = gradient;
            ctx.fill();

            // 棋子边缘
            ctx.strokeStyle = player === 1 ? '#333' : '#eee';
            ctx.lineWidth = 1;
            ctx.stroke();
        }

        // 绘制胜利线
        function drawWinLine(positions) {
            if (positions.length < 5) return;

            const first = positions[0];
            const last = positions[positions.length - 1];

            const x1 = BOARD_PADDING + first.y * CELL_SIZE;
            const y1 = BOARD_PADDING + first.x * CELL_SIZE;
            const x2 = BOARD_PADDING + last.y * CELL_SIZE;
            const y2 = BOARD_PADDING + last.x * CELL_SIZE;

            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.strokeStyle = '#FF4500';
            ctx.lineWidth = 4;
            ctx.setLineDash([8, 4]);
            ctx.stroke();
            ctx.setLineDash([]);
        }

        // 坐标转换：从鼠标位置到棋盘格子
        function getBoardPosition(clientX, clientY) {
            const rect = canvas.getBoundingClientRect();
            const x = clientX - rect.left;
            const y = clientY - rect.top;

            const col = Math.round((x - BOARD_PADDING) / CELL_SIZE);
            const row = Math.round((y - BOARD_PADDING) / CELL_SIZE);

            if (row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE) {
                return { row, col };
            }

            return null;
        }

        // 检查是否有玩家获胜
        function checkWin(row, col, player) {
            const directions = [
                [0, 1],   // 水平
                [1, 0],   // 垂直
                [1, 1],   // 对角线
                [1, -1]   // 反对角线
            ];

            for (const [dx, dy] of directions) {
                let count = 1;  // 当前位置已经有一个棋子
                let winPositions = [{x: row, y: col}];

                // 正方向检查
                for (let i = 1; i < 5; i++) {
                    const newRow = row + i * dx;
                    const newCol = col + i * dy;

                    if (newRow < 0 || newRow >= BOARD_SIZE || newCol < 0 || newCol >= BOARD_SIZE) {
                        break;
                    }

                    if (gameBoard[newRow][newCol] === player) {
                        count++;
                        winPositions.push({x: newRow, y: newCol});
                    } else {
                        break;
                    }
                }

                // 反方向检查
                for (let i = 1; i < 5; i++) {
                    const newRow = row - i * dx;
                    const newCol = col - i * dy;

                    if (newRow < 0 || newRow >= BOARD_SIZE || newCol < 0 || newCol >= BOARD_SIZE) {
                        break;
                    }

                    if (gameBoard[newRow][newCol] === player) {
                        count++;
                        winPositions.push({x: newRow, y: newCol});
                    } else {
                        break;
                    }
                }

                if (count >= 5) {
                    return winPositions;
                }
            }

            return null;
        }

        // 检查棋盘是否已满
        function isBoardFull() {
            for (let i = 0; i < BOARD_SIZE; i++) {
                for (let j = 0; j < BOARD_SIZE; j++) {
                    if (gameBoard[i][j] === 0) {
                        return false;
                    }
                }
            }
            return true;
        }

        // 切换当前玩家
        function switchPlayer() {
            currentPlayer = currentPlayer === 1 ? 2 : 1;

            // 更新UI显示
            currentPlayerIcon.className = 'w-8 h-8 rounded-full stone-shadow';
            currentPlayerIcon.classList.add(currentPlayer === 1 ? 'bg-blackStone' : 'bg-whiteStone');
            currentPlayerText.textContent = currentPlayer === 1 ? '黑方回合' : '白方回合';
        }

        // 添加历史记录
        function addHistory(message) {
            const li = document.createElement('li');
            li.textContent = message;
            li.className = 'animate-fadeIn';
            gameHistory.appendChild(li);
            gameHistory.scrollTop = gameHistory.scrollHeight;
        }

        // 处理落子
        function handleMove(row, col) {
            if (gameOver || gameBoard[row][col] !== 0) {
                return false;
            }

            // 记录这一步
            gameBoard[row][col] = currentPlayer;
            moveHistory.push({row, col, player: currentPlayer});

            // 更新UI
            drawBoard();

            // 添加历史记录
            const playerName = currentPlayer === 1 ? '黑方' : '白方';
            addHistory(`${playerName}在(${col+1},${row+1})落子`);

            // 检查是否获胜
            const winPositions = checkWin(row, col, currentPlayer);
            if (winPositions) {
                gameOver = true;
                gameStatus.textContent = '游戏结束';
                gameStatus.className = 'text-sm px-3 py-1 rounded-full bg-red-100 text-red-800';

                // 绘制胜利线
                drawWinLine(winPositions);

                // 显示胜利消息
                winnerText.textContent = `${playerName}获胜！`;
                winMessage.classList.remove('hidden');

                return true;
            }

            // 检查是否平局
            if (isBoardFull()) {
                gameOver = true;
                gameStatus.textContent = '游戏结束';
                gameStatus.className = 'text-sm px-3 py-1 rounded-full bg-yellow-100 text-yellow-800';

                // 显示平局消息
                winnerText.textContent = '平局！';
                winMessage.classList.remove('hidden');

                return true;
            }

            // 切换玩家
            switchPlayer();

            // 清除提示
            hintPosition = null;

            return true;
        }

        // 简单的AI提示（寻找可能的最佳位置）
        function getHintPosition() {
            // 检查自己的获胜位置
            for (let i = 0; i < BOARD_SIZE; i++) {
                for (let j = 0; j < BOARD_SIZE; j++) {
                    if (gameBoard[i][j] === 0) {
                        // 模拟落子
                        gameBoard[i][j] = currentPlayer;
                        const winPositions = checkWin(i, j, currentPlayer);
                        gameBoard[i][j] = 0; // 撤销模拟

                        if (winPositions) {
                            return {x: i, y: j};
                        }
                    }
                }
            }

            // 检查对手的获胜位置
            const opponent = currentPlayer === 1 ? 2 : 1;
            for (let i = 0; i < BOARD_SIZE; i++) {
                for (let j = 0; j < BOARD_SIZE; j++) {
                    if (gameBoard[i][j] === 0) {
                        // 模拟落子
                        gameBoard[i][j] = opponent;
                        const winPositions = checkWin(i, j, opponent);
                        gameBoard[i][j] = 0; // 撤销模拟

                        if (winPositions) {
                            return {x: i, y: j};
                        }
                    }
                }
            }

            // 简单策略：找一个靠近已有棋子的位置
            for (let i = 0; i < BOARD_SIZE; i++) {
                for (let j = 0; j < BOARD_SIZE; j++) {
                    if (gameBoard[i][j] === 0) {
                        // 检查周围是否有棋子
                        for (let dx = -2; dx <= 2; dx++) {
                            for (let dy = -2; dy <= 2; dy++) {
                                const nx = i + dx;
                                const ny = j + dy;

                                if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny < BOARD_SIZE) {
                                    if (gameBoard[nx][ny] !== 0) {
                                        return {x: i, y: j};
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // 如果没有找到任何位置，返回棋盘中心附近的位置
            return {x: Math.floor(BOARD_SIZE/2), y: Math.floor(BOARD_SIZE/2)};
        }

        // 重置游戏
        function resetGame() {
            gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(0));
            currentPlayer = 1;
            gameOver = false;
            moveHistory = [];
            hintPosition = null;

            // 更新UI
            drawBoard();
            currentPlayerIcon.className = 'w-8 h-8 rounded-full bg-blackStone stone-shadow';
            currentPlayerText.textContent = '黑方回合';
            gameStatus.textContent = '游戏进行中';
            gameStatus.className = 'text-sm px-3 py-1 rounded-full bg-green-100 text-green-800';

            // 清空历史记录
            gameHistory.innerHTML = '<li class="text-gray-500 italic">游戏开始</li>';

            // 隐藏胜利消息
            winMessage.classList.add('hidden');
        }

        // 悔棋
        function undoMove() {
            if (moveHistory.length === 0 || gameOver) {
                return;
            }

            const lastMove = moveHistory.pop();
            gameBoard[lastMove.row][lastMove.col] = 0;

            // 切换回上一个玩家
            currentPlayer = lastMove.player;

            // 更新UI
            drawBoard();
            currentPlayerIcon.className = 'w-8 h-8 rounded-full stone-shadow';
            currentPlayerIcon.classList.add(currentPlayer === 1 ? 'bg-blackStone' : 'bg-whiteStone');
            currentPlayerText.textContent = currentPlayer === 1 ? '黑方回合' : '白方回合';

            // 更新历史记录
            gameHistory.removeChild(gameHistory.lastChild);

            // 清除提示
            hintPosition = null;
        }

        // 显示提示
        function showHint() {
            if (gameOver) {
                return;
            }

            hintPosition = getHintPosition();
            drawBoard();

            // 添加历史记录
            const playerName = currentPlayer === 1 ? '黑方' : '白方';
            addHistory(`为${playerName}提供提示：(${hintPosition.y+1},${hintPosition.x+1})`);
        }

        // 事件监听
        canvas.addEventListener('click', (e) => {
            const pos = getBoardPosition(e.clientX, e.clientY);
            if (pos) {
                handleMove(pos.row, pos.col);
            }
        });

        restartBtn.addEventListener('click', resetGame);
        undoBtn.addEventListener('click', undoMove);
        hintBtn.addEventListener('click', showHint);
        newGameBtn.addEventListener('click', resetGame);

        // 窗口大小调整时重绘棋盘
        window.addEventListener('resize', () => {
            const tempBoard = [...gameBoard.map(row => [...row])];
            setupCanvas();
            gameBoard = tempBoard;
            drawBoard();
        });

        // 初始化游戏
        setupCanvas();
        drawBoard();
    });
</script>
</body>
</html>
